#ifndef __RUNNING_HPP_
#define __RUNNING_HPP_
#include "gc.h"
#include "gc_cpp.h"
#include "gc_allocator.h"

#include "vm/vm.hpp"
#include "vm/opcodes.hpp"
#include "rep/rep.hpp"

using namespace std;
using namespace __gnu_cxx;

namespace rep{


  class Lambda{
  public:
    Lambda(FrameType* typ, Block* b) :
      lex(typ),
      code(b){
    }
    FrameType* scope(){return lex;}
    Block* body(){return code;}

    Continuation apply(Cons* stack, Slot* env, int argnum,
                       Continuation* ret, Continuation* except,
                       Continuation* yield, Continuation* ifdone, 
                       Continuation* br, Continuation* cont);
  private:
    FrameType* lex; //this becomes the type of the frame to hang
    Block* code;
  };

  class Block{
  public:
    vector<vm::Instruction> code;
  };


  class Continuation{
  public:
    Continuation(Cons* s, Slot* e, Block* c, int o) :
      stack (s),
      env (e),
      code (c),
      offset (o) {}
    Cons* stack;
    Slot* env;
    Block* code;
    int offset;
    bool ended();
    Continuation next();
    Continuation pop(Slot* fill);
    Continuation push(const Slot& ret);
  };

  class ContinuationHelper{
  public:
    static void assign(Slot* to, Continuation* cont);
  };


};

#endif
